/*
 *  VerticalPlatform.m
 *  pogostick
 *
 *  Created by daddy (chuck@kollar.com) on 9/11/09.
 *  Copyright 2009 Charles P. Kollar All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "VerticalPlatform.h"


@implementation VerticalPlatform

@synthesize rise_height;


-(id)initInSpace: (cpSpace *)sp staticBody:(cpBody *)sb identifier:(NSString *)ident atPosition:(cpVect)p size:(cpVect)sz
{
    return [self initInSpace: sp staticBody: sb identifier: ident atPosition: p size: sz wallWidth: 5.0f];
}

-(id)initInSpace: (cpSpace *)sp staticBody:(cpBody *)sb identifier:(NSString *)ident atPosition:(cpVect)p size:(cpVect)sz wallWidth:(cpFloat)ww
{
	if (self = [super init]) {
        identifier = ident;
		space = sp;
		staticBody = sb;
        // p is the center of the rectangle that forms the moving space of the level
        // initially the level is created at the bottom of this rectangle...
        cpVect center = cpvadd(p, cpv(0.0f,-sz.y/2));
		wall_width = ww;
		box_width = sz.x*0.5f; // verts goes from -box_width to + box_width
		rise_height = sz.y;
		
		cpVect verts[] = {
			cpv(-box_width,-wall_width),
			cpv(-box_width,wall_width),
			cpv(box_width,wall_width),
			cpv(box_width,-wall_width)
		};
		// Instead of using a gear joint to fix the platform's rotation, use an infinite moment of inertia.
		// This makes the platform completely unrotatable by any force applied to it.
		// Doing this will not only use less CPU, and act more solid and stable. Do this for both types of platforms.
		platformBody = cpBodyNew(PLATFORM_MASS, INFINITY);
		platformBody->p = center;
		cpSpaceAddBody(space, platformBody);
        
		shape = cpPolyShapeNew(platformBody, (sizeof(verts)/sizeof(cpVect)), verts, cpvzero);
		shape->e = 0.0; shape->u = 1.0;
		shape->collision_type = kColl_Ground;
		cpSpaceAddShape(space, shape);
		joint = cpGrooveJointNew(staticBody, platformBody, center, cpv(center.x,center.y+rise_height), cpvzero);
		cpSpaceAddConstraint(space, joint);
	}
	
	return self;
}

-(void) dealloc {
    //cpConstraintFree(joint);
    //cpShapeFree(shape);
	//cpBodyFree(platformBody);
    
    [super dealloc];
}

-(void)performActions
{
    cpVect pos = platformBody->p;// location of the platform body
    
    // give the platform a constant velocity till it reaches the top of it's travel
    cpGrooveJoint *j = (cpGrooveJoint *)joint;
    cpVect bottom = j->grv_a;
    cpVect top = j->grv_b;
    if (pos.y >= top.y) {
        direction = -1; // down
        platformBody->v = cpv(0.0f, SPACE_GRAVITY*1.5); platformBody->w = 0.0f;
    } else if (pos.y <= bottom.y) {
        direction = 1; // up
        platformBody->v = cpv(0.0f, -SPACE_GRAVITY*1.5); platformBody->w = 0.0f;
    }
    cpBodyApplyImpulse(platformBody, cpv(0.0f, (direction == -1) ? SPACE_GRAVITY : -SPACE_GRAVITY), cpvzero);
}

@end
